<?php

namespace app\common\http;

use GatewayWorker\Lib\Gateway;
use think\facade\Cache;
use think\worker\Events;

class GatewayWork extends Events
{
    /**
     * onConnect 事件回调
     * 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
     *
     * @access public
     * @param int $client_id
     * @return void
     */
    public static function onConnect($client_id)
    {
        Gateway::sendToClient($client_id, json_encode(array(
            'type' => 'init',
            'client_id' => $client_id
        )));
    }

    /**
     * onWebSocketConnect 事件回调
     * 当客户端连接上gateway完成websocket握手时触发
     *
     * @param integer $client_id 断开连接的客户端client_id
     * @param mixed $data
     * @return void
     */
    public static function onWebSocketConnect($client_id, $data)
    {

    }

    /**
     * onMessage 事件回调
     * 当客户端发来数据(Gateway进程收到数据)后触发
     *
     * @access public
     * @param int $client_id
     * @param mixed $data
     * @return void
     */
    public static function onMessage($client_id, $data)
    {
        $data = json_decode($data, true);
        // 绑定uid {"type":"bind","uid":""}
        if ($data['type'] == 'bind') {
            Gateway::bindUid($client_id, $data['uid']);

            // 发送离线消息
            $redis = Cache::store('redis')->handler();
            $key   = "message:{$data['uid']}";
            while ($redis->llen($key)) {
                Gateway::sendToUid($data['uid'], $redis->rpop($key));
            }
        }

        // 发送消息 {"type":"message","data":{"mine":{"id":"","username":"","avatar":"","content":"","mine":"true"},"to":{"id":"","username":"","avatar":"","type":"friend"}}}
        if ($data['type'] == 'message') {
            // 消息格式
            $message = [
                'type' => 'message',
                'data' => [
                    'id'        => $data['data']['mine']['id'],
                    'username'  => $data['data']['mine']['username'],
                    'avatar'    => $data['data']['mine']['avatar'],
                    'content'   => $data['data']['mine']['content'],
                    'type'      => 'friend',
                    "mine"      => false,
                    "timestamp" => time() * 1000
                ]
            ];
            $message = json_encode($message, JSON_UNESCAPED_UNICODE);

            if (!Gateway::isUidOnline($data['data']['to']['id'])) {
                // 离线保存消息
                Cache::store('redis')->handler()->lpush("message:{$data['data']['to']['id']}", $message);

                $message = [
                    'type' => 'offline',
                    'data' => [
                        'id'        => $data['data']['to']['id'],
                        'username'  => $data['data']['to']['username'],
                        'avatar'    => $data['data']['to']['avatar'],
                        'content'   => '当前不在线, 有事请留言',
                        'type'      => 'friend',
                        "mine"      => false,
                        "timestamp" => time() * 1000
                    ]
                ];
                Gateway::sendToUid($data['data']['mine']['id'], json_encode($message, JSON_UNESCAPED_UNICODE));
            } else {
                // 在线发送消息
                Gateway::sendToUid($data['data']['to']['id'], $message);
            }
        }
    }

    /**
     * onClose 事件回调 当用户断开连接时触发的方法
     *
     * @param integer $client_id 断开连接的客户端client_id
     * @return void
     */
    public static function onClose($client_id)
    {

    }

    /**
     * 后台消息推送
     * @param string $data
     * @param int $uid
     */
    public function sendMessage($data, $uid = 0)
    {
        if ($uid) {
            Gateway::sendToUid($uid, $data);// 给指定uid发送消息
        } else {
            Gateway::sendToAll($data);// 给所有人发送消息
        }
    }
}